package com.boruan.shengtangfeng.core.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.boruan.shengtangfeng.core.dao.*;
import com.boruan.shengtangfeng.core.entity.*;
import com.boruan.shengtangfeng.core.utils.*;
import com.boruan.shengtangfeng.core.vo.*;
import com.tencentyun.TLSSigAPIv2;
import org.apache.commons.lang3.RegExUtils;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.db.KeyHolder;
import org.beetl.sql.core.engine.PageQuery;
import org.bouncycastle.crypto.tls.TlsRSASigner;
import org.bouncycastle.jcajce.spec.TLSKeyMaterialSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.boruan.shengtangfeng.core.enums.Sex;
import com.boruan.shengtangfeng.core.exception.ServicesException;
import com.boruan.shengtangfeng.core.service.INoticeService;
import com.boruan.shengtangfeng.core.service.IUserService;
import com.boruan.shengtangfeng.core.vo.mapper.UserVoMapper;

import cn.jpush.api.JPushClient;

/**
 * @author liuguangqiang
 * @date 2016年8月10日 上午9:36:16
 */
@Service
@Transactional(readOnly = true)
public class UserService implements IUserService {
    private static Logger logger = LoggerFactory.getLogger(UserService.class);
    @Autowired
    private IUserDao userDao;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private SQLManager sqlManager;
    @Autowired
    private JPushClient jPushClient;
    @Autowired
    private IArticleCommentDao articleCommentDao;
    @Autowired
    private IArticleDao articleDao;
    @Autowired
    private IVideoDao videoDao;
    @Autowired
    private IQuestionCommentDao questionCommentDao;
    @Autowired
    private IVideoCommentDao videoCommentDao;
    @Autowired
    private INoticeService noticeService;
    @Autowired
    private IConfigDao configDao;
    @Autowired
    private IUserBlackListDao userBlackListDao;
    @Autowired
    private IReportReasonsDao reportReasonsDao;
    @Autowired
    private IUserReportDao userReportDao;
    @Autowired
    private IUserFriendAndBlacklistDao userFriendAndBlacklistDao;
    @Autowired
    private IClassAndDao classAndDao;
    @Autowired
    private IClassMembersDao classMembersDao;
    @Autowired
    private IClassParameterDao classParameterDao;
    @Value("${tencent.secretid}")
    private Long SECRETID;
    @Value("${tencent.secretkey}")
    private String SECRETKEY;
    @Autowired
    private IAreaDao areaDao;
    @Autowired
    private IScreenNameDao screenNameDao;
    @Autowired
    private IAttentionDao attentionDao;


    @Value("${aliyun.sms.product}")
    private String product;
    @Value("${aliyun.sms.domain}")
    private String domain;
    @Value("${aliyun.sms.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.sms.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.sms.templateCode.register}")
    private String templateCodeRegister;
    @Value("${aliyun.sms.templateCode.login}")
    private String templateCodeLogin;
    @Value("${aliyun.sms.templateCode.changePassword}")
    private String templateCodeChangePassword;
    @Value("${aliyun.sms.templateCode.changeMobile}")
    private String templateCodeChangeMobile;
    @Value("${aliyun.sms.signName}")
    private String signName;


    /**
     * 后台查询用户信息
     *
     * @author liuguangqiang
     * @date 2016年8月10日 上午9:36:16
     */
    @Override
    public User findById(Long id) {
        return userDao.unique(id);
    }

    @Override
    public void pageQuery(PageQuery<User> pageQuery, User user) {
        pageQuery.setParas(user);
        userDao.pageQuery(pageQuery);
        for (User user1 : pageQuery.getList()) {
            //粉丝数
            long fansCount = attentionDao.createLambdaQuery().andEq(Attention::getIsDeleted, false).andEq(Attention::getFocusUserId, user1.getId()).count();
            user1.set("fansCount",fansCount);
        }
    }

    @Override
    @Transactional(readOnly = false)
    public boolean save(User user) {
        try {
            if (user.getId() == null) {
                KeyHolder kh = userDao.insertReturnKey(user);
                user.setId(kh.getLong());
            } else {
                userDao.updateById(user);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    @Override
    public User findByOpenId(String openId) {
        return userDao.findByOpenId(openId);
    }

    @Override
    @Transactional(readOnly = false)
    public void save(User user, String plainPassword) {
        user.setSalt(UserUtil.getSalt());
        user.setPassword(UserUtil.entryptPassword(plainPassword, user.getSalt()));
        if (user.getId() == null) {
            KeyHolder kh = userDao.insertReturnKey(user);
            user.setId(kh.getLong());
        } else {
            userDao.updateById(user);
        }
    }

    @Override
    public User findByMobile(String mobile) {
        return userDao.findByMobile(mobile);
    }

    @Override
    public List<User> findByTemplate(User user) {
        return userDao.template(user);
    }

    /**
     * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
     */
    public static void entryptPassword(User user) {
        byte[] salt = Digests.generateSalt(Global.SALT_SIZE);
        user.setSalt(Encodes.encodeHex(salt));

        byte[] hashPassword = Digests.sha1(user.getPassword().getBytes(), salt, Global.HASH_INTERATIONS);
        user.setPassword(Encodes.encodeHex(hashPassword));
    }

    @Override
    @Transactional(readOnly = false)
    public GlobalReponse changePassword(User user, String oldPassword, String password) {
        if (UserUtil.match(oldPassword, user.getPassword(), user.getSalt())) {
            user.setSalt(UserUtil.getSalt());
            user.setPassword(UserUtil.entryptPassword(password, user.getSalt()));
            userDao.updateById(user);
            return GlobalReponse.success();
        } else {
            return GlobalReponse.fail("旧密码错误");
        }
    }

    @Override
    public User getStudentById(Long id) {
        User student = userDao.single(id);
        return student;
    }

    @Override
    public List<User> getRank(Integer type, Integer size) {
        return userDao.getRank(type, size);
    }

    @Override
    public void insertUser(User user) {
        userDao.insert(user);
    }

    /**
     * @author: 刘光强
     * @Description: 处理绑定手机号
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    @Transactional(readOnly = false)
    public GlobalReponse<UserVo> changeMobile(String mobile, String authCode, Long userId) {
        User old = userDao.single(userId);
        if (!old.getChangeMobile()) {
            return GlobalReponse.fail("您已经修改过一次手机了");
        }
        String codeRedis = (String) redisTemplate.opsForValue().get(Consts.sendCode + mobile);
        if (!StringUtils.equals(authCode, codeRedis)) {
            return GlobalReponse.fail("验证码错误");
        } else {
            redisTemplate.delete(Consts.sendCode + mobile); // 验证成功删除redis存在的验证码
        }
        User user = userDao.findByMobile(mobile); // 根据手机号查用户是否注册过
        if (user == null) {
            // 用户不存在
            user = userDao.single(userId);
            user.setMobile(mobile);
            user.setLoginName(mobile);
            user.setChangeMobile(false);
            userDao.updateById(user);
            return GlobalReponse.success(UserVoMapper.MAPPER.toVo(user));
        } else {
            return GlobalReponse.fail("该手机号已绑定其他账号");
        }
    }

    /**
     * @author: 刘光强
     * @Description: 处理绑定手机号
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    public GlobalReponse checkOldMobile(String mobile, String authCode) {

        String codeRedis = (String) redisTemplate.opsForValue().get(Consts.sendCode + mobile);
        if (!StringUtils.equals(authCode, codeRedis)) {
            return GlobalReponse.fail("验证码错误");
        } else {
            redisTemplate.delete(Consts.sendCode + mobile); // 验证成功删除redis存在的验证码
            return GlobalReponse.success("审核通过");
        }
    }


    @Override
    @Transactional(readOnly = false)
    public GlobalReponse lockUser(Long id, Long userId, Integer type) {
        try {
            User user = new User();
            user.setId(id);
            user.setIsLocked(type == 0 ? false : true);
            user.setUpdateBy(userId.toString());
            user.setUpdateTime(new Date());
            userDao.updateTemplateById(user);

            Log sysLog = new Log();
            sysLog.setContent("用户管理删除用户信息");
            sysLog.setCreateTime(new Date());
            sysLog.setOperater(userId);
            sysLog.setObjectId(id);
            sysLog.setLogType(Log.LogType.ADMIN);
            sysLog.setOperateType(Log.OperateType.UPDATE);
            sqlManager.insert(sysLog);

            //推自定义消息让前端清空token
            if (user.getIsLocked()) {
                NoticeVo noticeVo = new NoticeVo();
                noticeVo.setUserId(id);
                noticeVo.setType(403);
                noticeVo.setTitle("账号被锁,强制下线");

                JPushMessage pushMessage = new JPushMessage();
                pushMessage.setMsgContent("账号被锁,强制下线");
                pushMessage.setExtras(new HashMap<String, String>() {{
                    put("code", "403");
                }});
                PushUtil.push(jPushClient, noticeVo, pushMessage);
            }


            return GlobalReponse.success();
        } catch (Exception e) {
            return GlobalReponse.fail();
        }
    }

    @Override
    @Transactional
    public void deleteComments(String ids, Integer type) {
        for (String id : ids.split(",")) {
            deleteComment(type, Long.parseLong(id));
        }

    }

    @Override
    @Transactional
    public GlobalReponse recommendComments(Long id, Integer type, Boolean recommend) {
        //试题评论
        if (type == 0) {
            QuestionComment questionComment = questionCommentDao.single(id);
//                if(recommend) {
//                    //判断超没超6个
//                    Config config=configDao.getKey(Consts.CONFIG_COMMENT_RECOMMEND_NUM);
//                    long maxCount=Long.parseLong(config.getValue());
//                    QuestionComment search = new QuestionComment();
//                    search.setQuestionId(questionComment.getQuestionId());
//                    search.setIsDeleted(false);
//                    long count=questionCommentDao.templateCount(search);
//                    if(count>=maxCount) {
//                        return GlobalReponse.fail("超过最大推荐数量："+maxCount);
//                    }
//                }
            questionCommentDao.updateById(questionComment);
        } else {
            ArticleComment articleComment = articleCommentDao.single(id);
            articleComment.setRecommend(recommend);
//                if(recommend) {
//                    //判断超没超6个
//                    Config config=configDao.getKey(Consts.CONFIG_COMMENT_RECOMMEND_NUM);
//                    long maxCount=Long.parseLong(config.getValue());
//                    ArticleComment search = new ArticleComment();
//                    search.setRecommend(true);
//                    search.setArticleId(articleComment.getArticleId());
//                    search.setIsDeleted(false);
//                    long count=articleCommentDao.templateCount(search);
//                    if(count>=maxCount) {
//                        return GlobalReponse.fail("超过最大推荐数量："+maxCount);
//                    }
//                }
            articleCommentDao.updateById(articleComment);
        }
        return GlobalReponse.success();
    }

    @Override
    public List<User> getMySpread(Long userId, Boolean isVip) {
        return userDao.getMySpread(userId, isVip);
    }


    @Override
    @Transactional
    public void addUser(User user) {
        User search = userDao.findByMobile(user.getMobile()); // 根据手机号查用户是否注册过
        if (search != null) {
            throw new ServicesException("用户已经存在或已被删除，不可再次添加", GlobalReponseResultEnum.FAIL.getCode());
        } else {
            user = buildNewUser(user.getMobile(), null, user.getPassword(), null);
        }
    }

    /**
     * @return
     * @description: 获赞数加1
     * @Param
     * @author KongXH
     * @date 2020/8/17 17:30
     */
    @Override
    public void plusLikeNum(Long id) {
        userDao.plusLikeNum(id);
    }

    /**
     * @return
     * @description: 获赞数减1
     * @Param
     * @author KongXH
     * @date 2020/8/17 17:30
     */
    @Override
    public void lessLikeNum(Long id) {
        userDao.lessLikeNum(id);

    }

    /**
     * @return
     * @description: 获取用户邀请码
     * @Param
     * @author KongXH
     * @date 2020/8/14 13:42
     */
    @Override
    public User findByInvitationCode(Long id) {
        return userDao.findByInvitationCode(id);
    }

    private User buildNewUser(String mobile, String openId, String password, Long spreadId) {
        User user = new User();
        user.setCreateTime(new Date());
        user.setIsDeleted(false);
        user.setIsLocked(false);
        user.setMobile(mobile);
//        user.setPunchNum(0);
//        user.setTotalPunch(0);
        user.setLoginName(mobile);
        if (StringUtils.isNotBlank(user.getMobile())) {
            user.setName(RegExUtils.replaceAll(user.getMobile(), "(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
        }
        Config config = configDao.getKey(Consts.CONFIG_USER_ICON);
        user.setHeadImage(config.getValue());
        user.setAccurate(new BigDecimal(0));
        user.setAnswerNum(0);
        user.setChangeMobile(true);
        user.setSex(Sex.UNKNOW);
        if (StringUtils.isNotBlank(password)) {
            user.setSalt(UserUtil.getSalt());
            user.setPassword(UserUtil.entryptPassword(password, user.getSalt()));
        } else {
//			user.setPassword(UserUtil.entryptPassword(UUIDUtil.getUUID(), user.getSalt()));
        }
        KeyHolder keyHolder = userDao.insertReturnKey(user);
        user.setId(keyHolder.getLong());

        return user;
    }


    @Override
    @Transactional
    public GlobalReponse deleteUserComment(Long userId, Integer type, Long commentId) {
        switch (type) {
            case 0:
                QuestionComment questionComment = questionCommentDao.single(commentId);
                if (questionComment.getUserId().equals(userId)) {
                    questionComment.setIsDeleted(true);
                    questionCommentDao.updateById(questionComment);

                } else {
                    return GlobalReponse.fail("你不能删别人的评论");
                }
                break;
            case 1:
                ArticleComment articleComment = articleCommentDao.single(commentId);
                if (articleComment.getUserId().equals(userId)) {
                    articleComment.setIsDeleted(true);
                    articleCommentDao.updateById(articleComment);
                    Article article = articleDao.single(articleComment.getArticleId());
                    article.setCommentNum(article.getCommentNum() - 1);
                    articleDao.updateById(article);
                } else {
                    return GlobalReponse.fail("你不能删别人的评论");
                }
                break;
            case 2:
                VideoComment videoComment = videoCommentDao.single(commentId);
                if (videoComment.getUserId().equals(userId)) {
                    videoComment.setIsDeleted(true);
                    videoCommentDao.updateById(videoComment);
                    Video video = videoDao.single(videoComment.getVideoId());
                    video.setCommentNum(video.getCommentNum() - 1);
                    videoDao.updateById(video);
                } else {
                    return GlobalReponse.fail("你不能删别人的评论");
                }
                break;
        }
        return GlobalReponse.success();
    }

    @Override
    public void pageComment(PageQuery<ArticleVideoCommentVo> pageQuery) {
        userDao.pageComment(pageQuery);
    }

    @Override
    @Transactional
    public GlobalReponse deleteComment(Integer type, Long commentId) {
        switch (type) {
            case 0:
                QuestionComment questionComment = questionCommentDao.single(commentId);
                questionComment.setIsDeleted(true);
                questionCommentDao.updateById(questionComment);

                break;
            case 1:
                ArticleComment articleComment = articleCommentDao.single(commentId);
                articleComment.setIsDeleted(true);
                articleCommentDao.updateById(articleComment);
                Article article = articleDao.single(articleComment.getArticleId());
                article.setCommentNum(article.getCommentNum() - 1);
                articleDao.updateById(article);
                break;
            case 2:
                VideoComment videoComment = videoCommentDao.single(commentId);
                videoComment.setIsDeleted(true);
                videoCommentDao.updateById(videoComment);
                Video video = videoDao.single(videoComment.getVideoId());
                video.setCommentNum(video.getCommentNum() - 1);
                videoDao.updateById(video);
                break;
        }
        return GlobalReponse.success();
    }

    @Override
    @Transactional
    public void updateCommentStatus(Long commentId, Integer type, Integer status) {
        switch (type) {
            case 0:
                QuestionComment questionComment = questionCommentDao.single(commentId);
                questionComment.setStatus(status);
                questionCommentDao.updateById(questionComment);

                break;
            case 1:
                ArticleComment articleComment = articleCommentDao.single(commentId);
                articleComment.setStatus(status);
                articleCommentDao.updateById(articleComment);
                break;
            case 2:
                VideoComment videoComment = videoCommentDao.single(commentId);
                videoComment.setStatus(status);
                videoCommentDao.updateById(videoComment);
                break;
        }
    }

    /**
     * @author: 刘光强
     * @Description: 修改手机号时向用户绑定的手机发送验证码
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    public GlobalReponse<String> sendCode(Long userId) {
        try {
            // 初始化acsClient,暂不支持region化
            User user = userDao.single(userId);
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(user.getMobile());
            request.setSignName(signName);
            request.setTemplateCode(templateCodeChangeMobile);
            String code = StringUtils.createCharacterNumber();
//            code = "000000";
            request.setTemplateParam("{code:" + code + "}");
            redisTemplate.opsForValue().set(Consts.sendCode + user.getMobile(), code, 5, TimeUnit.MINUTES);
//            return GlobalReponse.success("验证码发送成功", code);
            SendSmsResponse response = acsClient.getAcsResponse(request);
            if ("OK".equals(response.getCode())) {
                redisTemplate.opsForValue().set(Consts.sendCode + user.getMobile(), code, 5, TimeUnit.MINUTES);
                return GlobalReponse.success("验证码发送成功", code);
            } else {
                return GlobalReponse.fail(response.getMessage());
            }

        } catch (Exception e) {
            e.printStackTrace();
            return GlobalReponse.fail("发送验证码失败！");
        }
    }

    /**
     * @author: 刘光强
     * @Description: 修改手机号时校验验证码
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    public GlobalReponse<String> checkCode(Long userId, String code) {
        try {
            // 初始化acsClient,暂不支持region化
            User user = userDao.single(userId);
            String codeRedis = (String) redisTemplate.opsForValue().get(Consts.sendCode + user.getMobile());
            if (!StringUtils.equals(code, codeRedis)) {
                return GlobalReponse.fail("验证码错误");
            } else {
                redisTemplate.delete(Consts.sendCode + user.getMobile()); // 验证成功删除redis存在的验证码
            }
            return GlobalReponse.success();
        } catch (Exception e) {
            e.printStackTrace();
            return GlobalReponse.fail("校验验证码失败！");
        }
    }

    /**
     * @author: 刘光强
     * @Description: 修改手机号时
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    @Transactional
    public GlobalReponse<String> bindMobile(Long userId, String mobile, String code) {
        try {
            // 初始化acsClient,暂不支持region化
            User user = userDao.single(userId);
            String codeRedis = (String) redisTemplate.opsForValue().get(Consts.sendCode + mobile);
            if (!StringUtils.equals(code, codeRedis)) {
                return GlobalReponse.fail("验证码错误");
            } else {
                redisTemplate.delete(Consts.sendCode + mobile); // 验证成功删除redis存在的验证码
            }
            User temp = userDao.findByMobile(mobile);
            if (temp != null) {
                return GlobalReponse.fail("该手机号已经绑定其他用户");
            }
            user.setMobile(mobile);
            user.setLoginName(mobile);
            userDao.updateById(user);
            return GlobalReponse.success();
        } catch (Exception e) {
            e.printStackTrace();
            return GlobalReponse.fail("校验验证码失败！");
        }
    }

    @Override
    @Transactional
    public void blackUser(Long userId, Long blackUserId) {
        //添加到用户黑名单
        UserBlackList search = new UserBlackList();
        search.setBlackUserId(blackUserId);
        search.setUserId(userId);
        search.setCreateBy(userId + "");
        search.setCreateTime(new Date());
        userBlackListDao.insert(search);
    }


    @Override
    public GlobalReponse<String> newCheck() {
        return null;
    }

    /**
     * 审核端将用户封号或者解封
     *
     * @param userId
     * @return
     */
    @Override
    @Transactional(readOnly = false)
    public GlobalReponse blockOrUnblockUser(Long adminId, Long userId, Integer status) {
        User user = userDao.createLambdaQuery().andEq(User::getId, userId).single();
        if (user != null) {
            if (status == 1) {
                if (user.getIsLocked() == true) {
                    return GlobalReponse.fail("请勿重复操作");
                }
                user.setIsLocked(true);
                user.setUpdateBy(adminId.toString());
                user.setUpdateTime(new Date());
                userDao.updateTemplateById(user);
                return GlobalReponse.success("封号成功");
            } else if (status == 0) {
                if (user.getIsLocked() == false) {
                    return GlobalReponse.fail("请勿重复操作");
                }
                user.setIsLocked(false);
                user.setUpdateBy(adminId.toString());
                user.setUpdateTime(new Date());
                userDao.updateTemplateById(user);
                return GlobalReponse.success("解封成功");
            }
        } else {
            return GlobalReponse.fail("用户不存在");
        }
        return GlobalReponse.fail("修改失败");
    }

    @Override
    public GlobalReponse<User> getUserStatus(Long userId) {
        User user = userDao.createLambdaQuery().andEq(User::getId, userId).single();
        if (user != null) {
            return GlobalReponse.success(user);
        }
        return GlobalReponse.fail("用户不存在");
    }

    @Override
    public GlobalReponse<List<ReportReasons>> getReportReason() {
        List<ReportReasons> list = reportReasonsDao.createLambdaQuery().andEq(ReportReasons::getIsDeleted, false).select();
        return GlobalReponse.success(list);
    }

    @Override
    public void saveReport(UserReport userReport) {
        userReportDao.insert(userReport);
    }

    @Override
    public boolean isFriend(Long userId, Long friendUser) {
        UserFriendAndBlacklist friend = userFriendAndBlacklistDao.isFriend(userId, friendUser);
        UserFriendAndBlacklist friend1 = userFriendAndBlacklistDao.isFriend1(userId, friendUser);
        if (friend != null || friend1 != null) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void toAuditReport(PageQuery<UserReport> pageQuery) {
        userReportDao.toAuditReport(pageQuery);
    }

    @Override
    public UserReport findReportById(Long reportId) {
        UserReport userReport = userReportDao.unique(reportId);
        return userReport;
    }

    @Override
    public void toAdminReport(PageQuery<UserReport> pageQuery) {
        userReportDao.toAdminReport(pageQuery);
    }

    @Override
    @Transactional(readOnly = false)
    public void dealUserReport(UserReport userReport) {
        userReportDao.updateById(userReport);
    }

    @Override
    public Long[] getReportUids(Long[] reportId) {
        List<UserReport> select = userReportDao.createLambdaQuery().andIn(UserReport::getId, Arrays.asList(reportId)).select();
        List<Long> collect = select.stream().map(UserReport::getPersonId).collect(Collectors.toList());
        Long[] uids = new Long[collect.size()];
        Long[] longs = collect.toArray(uids);
        return longs;
    }

    @Override
    public void batchDealReport(Long[] reportId, Integer status) {
        userReportDao.upStatusById(reportId, status);
    }

    @Override
    public void pageReportReason(PageQuery<ReportReasons> pageQuery) {
        reportReasonsDao.pageQuery(pageQuery);
    }


    @Override
    @Transactional(readOnly = false)
    public void saveReportReason(ReportReasons reportReasons) {
        if (reportReasons.getId() != null) {
            reportReasonsDao.updateTemplateById(reportReasons);
        } else {
            reportReasonsDao.insertTemplate(reportReasons);
        }
    }

    @Override
    public ReportReasons findReasonById(Long id) {
        ReportReasons reportReasons = reportReasonsDao.unique(id);
        return reportReasons;
    }

    @Override
    @Transactional(readOnly = false)
    public void delReport(Long reportId) {
        UserReport userReport = userReportDao.unique(reportId);
        userReport.setIsDeleted(true);
        userReportDao.updateById(userReport);
    }

    @Override
    public User findByIdTelName(Long userId) {
        return userDao.unique(userId);
    }

    /**
     * 删除举报理由
     *
     * @param id
     */
    @Override
    @Transactional(readOnly = false)
    public GlobalReponse delReportReasons(Long id) {
        ReportReasons reportReasons = reportReasonsDao.unique(id);
        reportReasons.setIsDeleted(true);
        reportReasonsDao.updateById(reportReasons);
        return GlobalReponse.success("删除成功");
    }

    /**
     * 获取UserSig
     *
     * @param
     * @param sdkappid
     * @param secretkey
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public GlobalReponse getUserSig(Long userId, Long sdkappid, String secretkey) {
        User user = userDao.unique(userId);
        long expire = (long) 60 * 60 * 24 * 7;
        TLSSigAPIv2 api = new TLSSigAPIv2(sdkappid, secretkey);
        String userSig = api.genSig(user.getId().toString(), expire);
        user.setUserSig(userSig);
        userDao.updateById(user);
        return GlobalReponse.success().setData(userSig);
    }

    @Override
    public GlobalReponse<GetClassInformVo> getClassInformById(Long classId) {
        ClassAnd classAnd = classAndDao.unique(classId);
        if (classAnd == null) {
            return GlobalReponse.fail("班级不存在");
        }
        GetClassInformVo informVo = new GetClassInformVo();
        informVo.setId(classAnd.getId());
        informVo.setClassNum(classAnd.getClassNum());
        long count = classMembersDao.createLambdaQuery().andEq(ClassMembers::getClassId, classAnd.getId()).andEq(ClassMembers::getIsDeleted, false).count();
        informVo.setMemberNum(count);
        //获取学年配置
        ClassParameter classParam = classParameterDao.createLambdaQuery().andEq(ClassParameter::getIsDeleted, false).single();
        int year = Integer.valueOf(classAnd.getSchoolYear());
        //判断学制
        int num = classParam.getEducationSystem() == 1 ? 5 : 6;
        //判断上下学期
        String now = new SimpleDateFormat("MM-dd").format(new Date());
        String spring = classParam.getSpringTime();
        String autumn = classParam.getAutumnTime();
        int newYear = year + 1;
        String nowTime = year + "-" + now;
        String springTime = year + "-" + spring;
        String autumnTime = newYear + "-" + autumn;
        Date date = null;
        Date date1 = null;
        Date date2 = null;
        String item = null;
        try {
            date = DateUtils.parseDate(nowTime, "yyyy-MM-dd");
            date1 = DateUtils.parseDate(springTime, "yyyy-MM-dd");
            date2 = DateUtils.parseDate(autumnTime, "yyyy-MM-dd");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (date.after(date1) && date.before(date2)) {
            item = "上";
        } else {
            item = "下";
        }
        Calendar cal = Calendar.getInstance();
        int yearD = cal.get(Calendar.YEAR);
        informVo.setName(classAnd.getSchoolYear() + "级" + "(" + NumberUtils.int2chineseNum(yearD - year + 1) + "年级" + item + ")" + classAnd.getName());

        return GlobalReponse.success(informVo);
    }

    /**
     * 赠送用户粉丝
     *
     * @param userId
     * @param fansNum
     * @param adminId
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public GlobalReponse giveUserFans(Long userId, Integer fansNum, Long adminId) {
        List<User> userList = userDao.getNotAttentionRobot(userId,fansNum);
        ArrayList<Attention> attentions = new ArrayList<>();
        for (User user : userList) {
            Attention attention = new Attention();
            attention.setUserId(user.getId());
            attention.setFocusUserId(userId);
            attention.setCreateBy(adminId.toString());
            attention.setCreateTime(new Date());
            attention.setIsDeleted(false);
            attentions.add(attention);
        }
        if (userList.size()<fansNum){
            for (int i = 0; i < fansNum - userList.size(); i++) {
                User robotUser = this.createRobotUser();
                Attention attention = new Attention();
                attention.setUserId(robotUser.getId());
                attention.setFocusUserId(userId);
                attention.setCreateBy(adminId.toString());
                attention.setCreateTime(new Date());
                attention.setIsDeleted(false);
                attentions.add(attention);
            }
        }
        attentionDao.insertBatch(attentions);
        return GlobalReponse.success();
    }

    @Transactional(readOnly = false)
    @Override
    public User createRobotUser() {
        User user = new User();
        user.setType(1);
        user.setChangeMobile(false);
        user.setIsLocked(false);
        user.setIsDeleted(false);
        user.setCreateTime(new Date());
        user.setAnswerNum(0);
        user.setCorrectNum(0);
        user.setIncorrectNum(0);
        user.setAccurate(new BigDecimal(0));
        user.setIntegral(0);
        user.setLikeNum(0);
        user.setShowLocation(0);
        Area province = areaDao.getOneProvince();
        Area city = areaDao.getOneCity(province.getId());
        user.setProvince(province.getName());
        user.setCity(city.getName());
        Random random = new Random();
        int i = random.nextInt(3);
        if (i==1){
            user.setSex(Sex.MALE);
        }else if (i==2){
            user.setSex(Sex.FEMALE);
        }else {
            user.setSex(Sex.UNKNOW);

        }
        user.setUserType(random.nextInt(2)+1);
        ScreenName screenName = screenNameDao.getRandomName();
        user.setName(screenName.getName());
//        user.setHeadImage();
        userDao.insert(user, true);

        Integer len = Math.toIntExact(8 - (user.getId() + "").length());
        user.setAccount(user.getId() + UUIDUtil.differentDigitsRandom(len));
        long expire = (long) 60 * 60 * 24 * 7;
        TLSSigAPIv2 api = new TLSSigAPIv2(SECRETID, SECRETKEY);
        String userSig = api.genSig(user.getId().toString(), expire);
        user.setUserSig(userSig);
        userDao.updateTemplateById(user);
        return user;
    }
}
